Skip to content

feat(venv): make wheel scripts runnable in venv#3743

Open
rickeylev wants to merge 85 commits intobazel-contrib:mainfrom
rickeylev:venv.bin.runnable
Open

feat(venv): make wheel scripts runnable in venv#3743
rickeylev wants to merge 85 commits intobazel-contrib:mainfrom
rickeylev:venv.bin.runnable

Conversation

@rickeylev
Copy link
Copy Markdown
Collaborator

@rickeylev rickeylev commented Apr 27, 2026

Currently, #!python based scripts in a wheel are put into the venv
as-is, so aren't actually runnable. Additionally, wheel entry points
aren't installed into the venv.

To fix, rewrite the scripts to re-exec themselves with the python3
binary in the same directory.

Also adds support for wheel entry points in venvs. This is done by
having the repo-phase parse entry_points.txt and defining a target for
each entry point. These targets run during build phase, so are able
to generate platform-specific outputs.

Cross-building with Windows is also added, supporting both Windows
as a target or exec platform to generate outputs for the target
platform.

Fixes #3202

ref https://packaging.python.org/en/latest/specifications/binary-distribution-format/#installing-a-wheel-distribution-1-0-py32-none-any-whl

for generic data scheme: these are usually installed to the venv root,
but that seems ill-advised. So we install into a data sub-directory
of the venv.
Uses os.name to correctly assert the Scripts/ and Include/ directory
paths when creating the virtual environment on Windows.
Also add debug info to venvs_site_packages_libs_test to help diagnose
Windows CI failures.
…addition

These changes seemed to cause many regressions in WORKSPACE mode in CI.
Also revert redundant bazel_skylib additions to example WORKSPACE files.
The original target was intended to be internal-only, so it has been
renamed and all references updated. No alias was added as per
instructions.
Copy link
Copy Markdown
Collaborator

@aignas aignas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really good, thank you very much!

Comment thread python/private/pypi/venv_entry_point_template.sh
Comment thread python/private/pypi/whl_extract.bzl
Comment thread python/private/pypi/whl_extract.bzl
Comment thread python/private/pypi/whl_library_targets.bzl Outdated
mrctx.rename(src, dest)
return

# Fallback for Bazel < 8.0
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With this, we may remove the wheel.py file because we have the right fallbacks.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we'd need this regardless? The starlark extract logic still has to look through the bin/ directory and and move files to rewrite-bin

Copy link
Copy Markdown
Collaborator

@aignas aignas Apr 29, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well as far as what the wheel.py is doing, we have reimplemented everything in starlark a while ago. The only reason why we still needed to have something like the wheel.py is to install sdists, or use pip. The extraction logic can be done fully in starlark.

@rickeylev
Copy link
Copy Markdown
Collaborator Author

Currently the py_console_script_binary is building a full runfiles tree and for the usecase that you are implementing in here - a py_binary is just calling utilities within the same venv that is a little bit too heavy. I want to separate the usecases for py_console_script_binary to be only something where we actually want to build a full separate venv for the said scripts.

Ah, I think I get what you mean. Do you want to file an issue for further discussion? entrypoints/scripts/things-in-bin seem distinct enough they warrant something in a provider, but it's not clear to me how a consumer can make effective use of it via a py_binary.

@rickeylev
Copy link
Copy Markdown
Collaborator Author

I got everything working except pythonw scripts under bazel 7. The root cause for this is wheel.py. We've hard-coded it to use a unix install format, so it rewrites #!pythonw to #!python. Later, when the rewrite tool goes to fixup the command line, it doesn't see pythonw, so can't generate the correct pythonw.exe part.

Since we're going to remove wheel.py, I've just skipped that particular test.

@rickeylev rickeylev added this pull request to the merge queue Apr 29, 2026
@github-merge-queue github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Apr 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support non-entry point declared executables in wheels

2 participants